#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <glib.h>
#include <string.h>
#include "ssb.h"

void iterator(gpointer key, gpointer value, gpointer user_data) {
 	printf("%s %d\n", key, *(int *)value);
}

void sort_and_print_hash(GHashTable * gb_hash){
	GHashTableIter iter;

	while(g_hash_table_size(gb_hash)>0){
		char * key =NULL, *min_key = NULL;
		int * value = NULL, *min_value = NULL;
		g_hash_table_iter_init(&iter,gb_hash);
		while (g_hash_table_iter_next (&iter, (gpointer)&key, (gpointer)&value)){
			if(min_key == NULL){
				min_key = key;
				min_value = value;
			}else{
				if(strcmp(min_key,key)>0){
					min_key = key;
					min_value = value;
				}
			}
		}
		printf("%s %d\n",min_key,*min_value);
		g_hash_table_remove(gb_hash,min_key);
	}
	return;
}

int main(int argc, char ** argv){
	int fp_date , fp_lo, fp_supplier,fp_part;
	struct ddate tmp_date, *p;
	struct part tmp_part, *p_part;
	struct supplier tmp_sp, * p_sp;
	struct lineorder tmp_lo;
	GHashTable * date_hash = NULL, *part_hash = NULL,*sp_hash=NULL;
	GHashTable * gb_hash = NULL;

	if(argc != 5){
		printf("error: data lo part supplier\n");
		exit(-1);
	}

	fp_date = open(argv[1],O_RDONLY);
	fp_lo = open(argv[2],O_RDONLY);
	fp_part = open(argv[3],O_RDONLY);
	fp_supplier = open(argv[4],O_RDONLY);

	date_hash = g_hash_table_new(NULL,NULL);
	part_hash = g_hash_table_new(NULL,NULL);
	sp_hash = g_hash_table_new(NULL,NULL);
	gb_hash = g_hash_table_new(g_str_hash,g_str_equal);

	while(read(fp_date,(void *)&tmp_date,sizeof(struct ddate))>0){
		p = (struct ddate *) malloc(sizeof(struct ddate));
		memcpy(p,&tmp_date,sizeof(struct ddate));
		g_hash_table_insert(date_hash,GINT_TO_POINTER(p->datekey),p);
	}

	while(read(fp_supplier,(void *)&tmp_sp,sizeof(struct supplier))>0){
		if(strncmp(tmp_sp.region,"EUROPE",6)!=0)
			continue;

		p_sp = (struct supplier *) malloc(sizeof(struct supplier));
		memcpy(p_sp,&tmp_sp,sizeof(struct supplier));
		g_hash_table_insert(sp_hash,GINT_TO_POINTER(p_sp->suppkey),p_sp);
	}

	while(read(fp_part,(void*)&tmp_part,sizeof(struct part))>0){
		if(strncmp(tmp_part.brand1,"MFGR#2239",9)!=0)
			continue;

		p_part = (struct part *)malloc(sizeof(struct part));
		memcpy(p_part,&tmp_part,sizeof(struct part));
		g_hash_table_insert(part_hash,GINT_TO_POINTER(p_part->partkey),p_part);

	}

	while(read(fp_lo,(void*)&tmp_lo,sizeof(struct lineorder))>0){
		p = (struct ddate *) g_hash_table_lookup(date_hash,GINT_TO_POINTER(tmp_lo.orderdate));
		if(p == NULL)
			continue;

		p_part = (struct part *) g_hash_table_lookup(part_hash,GINT_TO_POINTER(tmp_lo.partkey));
		if (p_part == NULL)
			continue;

		p_sp = (struct supplier*) g_hash_table_lookup(sp_hash,GINT_TO_POINTER(tmp_lo.suppkey));
		if (p_sp == NULL)
			continue;

		char* gb_key = NULL; 
		int * gb = NULL;
		int * sum = NULL;

		sum = (int *)malloc(sizeof(int ));
		gb_key = (char *) malloc(16*sizeof(char ));

		memset(gb_key,0,16*sizeof(char ));
		memset(sum,0,sizeof(int));

		sprintf(gb_key,"%d ",p->year);
		strncat(gb_key,p_part->brand1,9);
		gb = (int *) g_hash_table_lookup(gb_hash,gb_key);
		if (gb == NULL){
			*sum = tmp_lo.revenue;
			g_hash_table_insert(gb_hash,gb_key,sum);
		}else{
			*gb = *gb + tmp_lo.revenue;
			//g_hash_table_replace(gb_hash,gb_key,sum);
		}
	}

	//g_hash_table_foreach(gb_hash, (GHFunc)iterator, NULL);
	sort_and_print_hash(gb_hash);

	close(fp_date);
	close(fp_lo);
	close(fp_part);
	close(fp_supplier);
	return  0;
}
